#include <stdio.h>      // for printf()
#include <windows.h>    // for interacting with Windows

#define TILE_GRASS   0  // define some values to represent our terrain tiles
#define TILE_WALL    1
#define TILE_WATER   2
#define TILE_LAVA    3

#define MAX_MAP_WIDTH    256 // define a maximum size to our game map
#define MAX_MAP_DEPTH    256   

struct SMap // The struct is a block of variables to be used to store our map information
{
    int Width; // Declare Width and Depth variables which will hold the active map size
    int Depth;   
    int FloorCells[MAX_MAP_DEPTH][MAX_MAP_WIDTH]; // 2-Dimensional array of integers which can be accessed as FloorCells[y][x] and will hold values for representing the terrain
};

void setup( SMap* activeMap );  // Accepts as parameter an address pointing to an SMap
void update( SMap* activeMap ); // Accepts as parameter an address pointing to an SMap
void draw( SMap someMap );      // Accepts as parameter a copy of the contents of an SMap

int main ( void ) // start application from here
{
    SMap gameMap;      // declare a variable of type SMap
    setup( &gameMap ); // call setup() and send the address of our gameMap as parameter

    int frameCounter=0; // declare a variable for keeping track of the number of frame since execution began, where "int" stands for "integer"
   
    while( true ) // execute block {} while what's inside () is true
    {
        printf("Current frame number: %i\n", frameCounter);

        update( &gameMap );     // update frame, send map address to update() call
        draw( gameMap );        // render frame, send copy of the data to be displayed by draw()
        if(GetAsyncKeyState(VK_ESCAPE)) // check for escape key pressed
        {
            break; // exit while()
        }
        Sleep(150); // wait some time to give visual stability to the frame
        
        frameCounter = frameCounter+1;
    };
  
    return 0; // return an int
}

void setup( SMap* activeMap ) // Accepts an address pointing to an SMap
{
    printf("- setup() called.\n");

    activeMap->Width = 32; // Set a proper width for our map, which has to be less than MAX_MAP_WIDTH
    activeMap->Depth = 21; // Same for map depth   

    for( int z=0; z< activeMap->Depth; z = z+1 ) // iterate over every row
    {
        for( int x=0; x< activeMap->Width; x++ ) // iterate over every column for the z row
        {
            activeMap->FloorCells[z][x] = TILE_GRASS; // initialize the (x,z) map cell to "grass"
        }
    }

    // set a wall border
    for( int x=0; x< activeMap->Width; x++ )   
        activeMap->FloorCells[0][x] = TILE_WALL; // set all cells in the first row [0]   
    for( int x=0; x< activeMap->Width; x++ )       
        activeMap->FloorCells[activeMap->Depth-1][x] = TILE_WALL; // set all cells in the last row [depth-1]   
    for( int z=0; z< activeMap->Depth; z++ )   
        activeMap->FloorCells[z][0] = TILE_WALL; // set all cells in the first column [0]   
    for( int z=0; z< activeMap->Depth; z++ )   
        activeMap->FloorCells[z][activeMap->Width-1] = TILE_WALL; // set all cells in the last column [width-1]   
};

void update( SMap* activeMap )    // Accepts an address pointing to an SMap
{
    printf("- update() called.\n");
};

void draw( SMap someMap ) // Accepts a copy of the contents of an SMap
{
    printf("- draw() called.\n");
    for( int z=0; z< someMap.Depth; z++ ) // iterate over every row
    {
        for( int x=0; x< someMap.Width; x++ ) // iterate over every column for the z row
        {
            printf( "%c", someMap.FloorCells[z][x] ); // draw the contents of the cell at (x,z) as an ascii character
        }
        printf( "\n" ); // \n is the code character for "new line" inside a text. We use it to display the next cells in the next row.
    }
};
